package com.hn658.base.message.notisender.sender.comet;

import java.io.IOException;

import javax.servlet.AsyncContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.hn658.base.message.common.dto.NotificationDTO;
import com.hn658.base.message.common.enums.NotifySenderType;
import com.hn658.base.message.notisender.exception.CometException;
import com.hn658.base.message.notisender.exception.NotiSenderException;
import com.hn658.base.message.notisender.message.CometMessage;
import com.hn658.base.message.notisender.sender.AbstractMessageSender;
import com.hn658.framework.logging.enums.LogCategory;

@Component("cometMessageSender")
public class CometMessageSender extends AbstractMessageSender<CometMessage>{
	
	@Autowired
	private IIsOnlineManager isOnlineManager;

	@Override
	public void send(CometMessage message) {
		NotificationDTO dto = (NotificationDTO)message.getDto();
		String appId = dto.getAppId();
		String uid = dto.getToUid();
		String messageJson = dto.getNotifyData();
		String appUid=uid+"_"+appId;
		//获取应用对应的长连接
		AsyncContext context = AsyncContextCache.get(appUid);
	    if (context == null) {
	        logger.debug(LogCategory.SYSTEM,"当前ASYNC_CONTEXT_QUEUE不存在编号为：{}的长连接，return", appUid);
	        return;
	    }

	    if (null != context) {
	        logger.debug(LogCategory.SYSTEM,"向appId:{},uid:{}推送消息.", new Object[]{appId, uid});
	        synchronized (context) {
	            logger.debug(LogCategory.SYSTEM,"向appId:{},uid:{}推送消息. 内容 {}", new Object[]{appId, uid,
	            		messageJson});
	            try {
					context.getResponse().getWriter().print(messageJson+"|------|");
					context.getResponse().getWriter().flush();
				} catch (IOException e) {
					throw new CometException(CometException.IOException);
				}
	        }

	        // 推送失败，移除长链接
	        try {
				if (context.getResponse().getWriter().checkError()) {
				    logger.debug(LogCategory.SYSTEM,"长链接 编号为:{} 发送数据出错，将其结束.",appUid);
				    AsyncContextCache.remove(appUid);
				    logger.debug(LogCategory.SYSTEM,"设置用户appId :{}, uid :{} 在线状态为已离线.", new Object[]{appId, uid});
				    isOnlineManager.offline(appId,uid);
				    context.complete();
				} else {
					// 设置用户在线
				    logger.debug(LogCategory.SYSTEM,"推送成功，设置用户appId :{}, uid :{} 在线状态.",new Object[]{appId, uid});
				    isOnlineManager.online(appId,uid);
				}
			} catch (IOException e) {
				throw new CometException(CometException.IOException);
			}
	    }
	}

	@Override
	public NotifySenderType getTarget() {
		return NotifySenderType.Comet;
	}

	public IIsOnlineManager getIsOnlineManager() {
		return isOnlineManager;
	}

	public void setIsOnlineManager(IIsOnlineManager isOnlineManager) {
		this.isOnlineManager = isOnlineManager;
	}
	
}
